package com.ys.service.base.impl;

import com.alibaba.fastjson.JSON;
import com.ys.entity.base.*;
import com.ys.entity.sys.YsCol;
import com.ys.mapper.base.TbUserMonthPerformanceMapper;
import com.ys.service.base.TbUserMonthPerformanceService;
import com.ys.util.CheckUtil;
import com.ys.vo.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 员工月度绩效信息
 */
@Service("tbUserMonthPerformanceService")
public class TbUserMonthPerformanceServiceImpl implements TbUserMonthPerformanceService {
	private static final Logger logger = LoggerFactory.getLogger(TbUserMonthPerformanceServiceImpl.class);

	@Autowired
	private TbUserMonthPerformanceMapper tbUserMonthPerformanceMapper;

	@Autowired
	private CheckUtil checkUtil;

	//通过员工职级管理新增
	@Override
	public R addByJobLevelManage(List<String> idList,String chooseMonth) throws Exception {
		int addCount = 0;
		for(String idStr : idList){
			Long jobLevelManageId = Long.parseLong(idStr);
			Map<String,Object> entity = new TbUserJobLevelManage()

					.addLeftJoin("TS_UserInfo U ON U.UserId = A.UserId")//用户信息表
					.addLeftJoin("TS_OrganizationInfo OI ON OI.Orgid = U.DeptId")
					.addField("OI.DeptName AS deptName")//部门

					.addLeftJoin("THR_UserArchives UAS ON UAS.UserId = A.UserId")//用户档案表
					.addField("UAS.UserState AS userState")//员工状态

					.addLeftJoin("TB_JobLevel J ON J.Id = A.RoleLevelId")//岗位职级表
					.addField("J.Rank AS rank")//岗位职级
					.addField("J.Category AS category")//岗位类别
					.addField("J.Categories AS categories")//职级大类
					.addField("J.Type AS type")//岗位工种
					.addField("J.JobPromotion AS jobBonus")//岗位提奖/月

					.addField("J.PerbasedSalary AS perbasedSalary")//绩效薪资/月
					.addField("J.QuarterlyBonus AS quarterlyBonus")//季度提奖/月
					.addField("J.SalaryStandard AS salaryStandard")//发薪标准/月
					.addField("J.BasicSalary AS basicSalary")//基本底薪/月
					.addField("J.PositionSalary AS positionSalary")//岗位薪资/月
					.addField("J.TransSubsidy AS transSubsidy")//交通补贴/月
					.addField("J.CateringSubsidy AS cateringSubsidy")//餐饮补贴/月
					.addField("J.FixsalaryStandard AS fixsalaryStandard")//定薪标准


					.addLeftJoin("TB_SocialSecurity S ON S.Id = A.SocialSecurityId")//社保管理表
					.addField("S.SoseBase AS soseBase")//社保基数
					.addField("S.PiUnitMonth AS piUnitMonth")//养老保险（单位）
					.addField("S.PiIndividualMonth AS piIndividualMonth")//养老保险（个人）
					.addField("S.UiUnitMonth AS uiUnitMonth")//失业保险（单位）
					.addField("S.UiIndividualMonth AS uiIndividualMonth")//失业保险（个人）
					.addField("S.WiiUnitMonth AS wiiUnitMonth")//工伤保险（单位）

					.addLeftJoin("TB_MedicalInsurance M ON M.Id = A.MedicalInsuranceId")//医保管理表
					.addField("M.MiBase AS miBase")//医保基数
					.addField("M.MiUnitMoonth AS miUnitMoonth")//医疗保险（单位）
					.addField("M.MiIndividualMonth AS miIndividualMonth")//医疗保险（个人）
					.addField("M.MiUnitMonth AS miUnitMonth")//生育保险（单位）

					.addLeftJoin("TB_ProvidentFund P ON P.Id = A.AccumulationFundId")//公积金管理表
					.addField("P.HousingPfBase AS housingPfBase")//公积金基数
					.addField("P.PfUnitMonth AS pfUnitMonth")//公积金（单位）
					.addField("P.PfIndividualMonth AS pfIndividualMonth")//公积金（个人）

					.addLeftJoin("TB_Attendance AD ON AD.Id = A.AttendanceId")//考勤管理表
					.addField("AD.Type AS attendanceType")//考勤类型
					.addField("AD.MonthlyAsDay AS monthlyAsDay")//月考勤标准（天）
					.addField("AD.DailyAsHour AS dailyAsHour")//日考勤标准（小时）/月
					.addField("AD.PaidPersonalLeave AS paidPersonalLeave")//带薪事假-其他（小时）

					.setId(jobLevelManageId)
					.setStatus(1)//停用不可推送
					.queryFirstMap();

			if(entity!=null){
				//查询用户工号(职级管理id)+年月是否已经推送过
				int hasPush = new TbUserMonthPerformance()
						.setPointMonth(chooseMonth)
						.setUserId(entity.get("userId").toString())
						.count();
				if(hasPush<=0){
					TbUserMonthPerformance tbUserMonthPerformance = JSON.parseObject(JSON.toJSONString(entity), TbUserMonthPerformance.class);
					tbUserMonthPerformance.setStatus(1);
					tbUserMonthPerformance.setPointMonth(chooseMonth);
					tbUserMonthPerformance.setUserJobLevelManageId(jobLevelManageId);
					if(entity.get("userId")!=null)tbUserMonthPerformance.setUserId(entity.get("userId").toString());
					if(entity.get("orgId")!=null)tbUserMonthPerformance.setOrgId(entity.get("orgId").toString());
					if(entity.get("deptName")!=null)tbUserMonthPerformance.setDeptName(entity.get("deptName").toString());
					if(entity.get("userState")!=null)tbUserMonthPerformance.setUserState(Integer.parseInt(entity.get("userState").toString()));
					if(entity.get("rank")!=null)tbUserMonthPerformance.setRank(entity.get("rank").toString());
					if(entity.get("type")!=null)tbUserMonthPerformance.setType(Integer.parseInt(entity.get("type").toString()));
					if(entity.get("category")!=null)tbUserMonthPerformance.setCategory(Integer.parseInt(entity.get("category").toString()));
					if(entity.get("categories")!=null)tbUserMonthPerformance.setCategories(Integer.parseInt(entity.get("categories").toString()));
					if(entity.get("soseBase")!=null)tbUserMonthPerformance.setSoseBase(new BigDecimal(entity.get("soseBase").toString()));
					if(entity.get("miBase")!=null)tbUserMonthPerformance.setMiBase(new BigDecimal(entity.get("miBase").toString()));
					if(entity.get("housingPfBase")!=null)tbUserMonthPerformance.setHousingPfBase(new BigDecimal(entity.get("housingPfBase").toString()));
					if(entity.get("attendanceType")!=null)tbUserMonthPerformance.setAttendanceType(entity.get("attendanceType").toString());
					if(entity.get("attendanceId")!=null)tbUserMonthPerformance.setAttendanceId(Long.parseLong(entity.get("attendanceId").toString()));
					if(entity.get("jobBonus")!=null)tbUserMonthPerformance.setJobBonus(new BigDecimal(entity.get("jobBonus").toString()));

					if(entity.get("roleLevelId")!=null)tbUserMonthPerformance.setRoleLevelId(Long.parseLong(entity.get("roleLevelId").toString()));
					if(entity.get("socialSecurityId")!=null)tbUserMonthPerformance.setSocialSecurityId(Long.parseLong(entity.get("socialSecurityId").toString()));
					if(entity.get("medicalInsuranceId")!=null)tbUserMonthPerformance.setMedicalInsuranceId(Long.parseLong(entity.get("medicalInsuranceId").toString()));
					if(entity.get("accumulationFundId")!=null)tbUserMonthPerformance.setAccumulationFundId(Long.parseLong(entity.get("accumulationFundId").toString()));

					//初始化考勤信息
					tbUserMonthPerformance.setWorkHour(BigDecimal.ZERO);//工作时长(小时)
					tbUserMonthPerformance.setAttendanceDay(BigDecimal.ZERO);//出勤天数
					tbUserMonthPerformance.setBusinessTripsDay(BigDecimal.ZERO);//出差天数
					tbUserMonthPerformance.setRestDay(BigDecimal.ZERO);//休息天数
					tbUserMonthPerformance.setNoWorkHour(BigDecimal.ZERO);//旷工(小时)
					tbUserMonthPerformance.setLateTimes(0);//迟到（次）
					tbUserMonthPerformance.setNoSignIn(0);//漏打卡（次）
					tbUserMonthPerformance.setYearHolidayHour(BigDecimal.ZERO);//年假（小时）
					tbUserMonthPerformance.setChildbirthHolidayHour(BigDecimal.ZERO);//产假（小时）
					tbUserMonthPerformance.setCompanionChildbirthHour(BigDecimal.ZERO);//陪产假（小时）
					tbUserMonthPerformance.setMarryHolidayHour(BigDecimal.ZERO);//婚假（小时）
					tbUserMonthPerformance.setDeathHolidayHour(BigDecimal.ZERO);//丧假（小时）
					tbUserMonthPerformance.setIllHolidayHour(BigDecimal.ZERO);//病假（小时）
					tbUserMonthPerformance.setThingHolidayHourByPublic(BigDecimal.ZERO);//事假-因公外出（小时）
					tbUserMonthPerformance.setThingHolidayHourByOther(BigDecimal.ZERO);//事假-其他（小时）

					//考勤状态
					tbUserMonthPerformance.setAttendanceStatus(0);
					//新增
					tbUserMonthPerformanceMapper.insert(tbUserMonthPerformance);
					addCount++;
				}
			}
		}
		return R.ok("成功推送"+addCount+"条!");
	}


	/**
	 * 保存
	 */
	@Override
	public R save(Map<String, Object> params,Long menuId) throws Exception {
		logger.info("员工月度绩效信息保存传参："+params);
		//参数验证
		String errorMsg = checkParams(params,menuId);
		if(errorMsg!=null && !"".equals(errorMsg)){
			return R.error(errorMsg);
		}
		TbUserMonthPerformance updateInfo = JSON.parseObject(JSON.toJSONString(params), TbUserMonthPerformance.class);

		tbUserMonthPerformanceMapper.update(updateInfo);

		TbUserMonthPerformance tbUserMonthPerformance = new TbUserMonthPerformance().setId(updateInfo.getId()).queryFirst();

		//修改保存的参数信息
		Map<String,Object> entity = new TbUserJobLevelManage()
				.clearFieldsSource()
				.addLeftJoin("TB_JobLevel J ON J.Id = A.RoleLevelId")//岗位职级表
				.addField("J.Rank AS rank")//岗位职级
				.addField("J.Category AS category")//岗位类别
				.addField("J.Categories AS categories")//职级大类
				.addField("J.Type AS type")//岗位工种
				.addField("J.JobPromotion AS jobBonus")//岗位提奖/月

				.addField("J.PerbasedSalary AS perbasedSalary")//绩效薪资/月
				.addField("J.QuarterlyBonus AS quarterlyBonus")//季度提奖/月
				.addField("J.SalaryStandard AS salaryStandard")//发薪标准/月
				.addField("J.BasicSalary AS basicSalary")//基本底薪/月
				.addField("J.PositionSalary AS positionSalary")//岗位薪资/月
				.addField("J.TransSubsidy AS transSubsidy")//交通补贴/月
				.addField("J.CateringSubsidy AS cateringSubsidy")//餐饮补贴/月
				.addField("J.FixsalaryStandard AS fixsalaryStandard")//定薪标准


				.addLeftJoin("TB_SocialSecurity S ON S.Id = A.SocialSecurityId")//社保管理表
				.addField("S.SoseBase AS soseBase")//社保基数
				.addField("S.PiUnitMonth AS piUnitMonth")//养老保险（单位）
				.addField("S.PiIndividualMonth AS piIndividualMonth")//养老保险（个人）
				.addField("S.UiUnitMonth AS uiUnitMonth")//失业保险（单位）
				.addField("S.UiIndividualMonth AS uiIndividualMonth")//失业保险（个人）
				.addField("S.WiiUnitMonth AS wiiUnitMonth")//工伤保险（单位）

				.addLeftJoin("TB_MedicalInsurance M ON M.Id = A.MedicalInsuranceId")//医保管理表
				.addField("M.MiBase AS miBase")//医保基数
				.addField("M.MiUnitMoonth AS miUnitMoonth")//医疗保险（单位）
				.addField("M.MiIndividualMonth AS miIndividualMonth")//医疗保险（个人）
				.addField("M.MiUnitMonth AS miUnitMonth")//生育保险（单位）

				.addLeftJoin("TB_ProvidentFund P ON P.Id = A.AccumulationFundId")//公积金管理表
				.addField("P.HousingPfBase AS housingPfBase")//公积金基数
				.addField("P.PfUnitMonth AS pfUnitMonth")//公积金（单位）
				.addField("P.PfIndividualMonth AS pfIndividualMonth")//公积金（个人）

				.addLeftJoin("TB_Attendance AD ON AD.Id = A.AttendanceId")//考勤管理表
				.addField("AD.Type AS attendanceType")//考勤类型
				.addField("AD.MonthlyAsDay AS monthlyAsDay")//月考勤标准（天）
				.addField("AD.DailyAsHour AS dailyAsHour")//日考勤标准（小时）/月
				.addField("AD.PaidPersonalLeave AS paidPersonalLeave")//带薪事假-其他（小时）
				.setId(tbUserMonthPerformance.getUserJobLevelManageId())
				.queryFirstMap();

		TbUserMonthPerformance tbUserMonthPerformanceByNew = JSON.parseObject(JSON.toJSONString(entity), TbUserMonthPerformance.class);
		tbUserMonthPerformanceByNew.setId(tbUserMonthPerformance.getId());
		tbUserMonthPerformanceMapper.update(tbUserMonthPerformanceByNew);
		
		return R.ok();
	}


	/**
	 * 删除
	 */
	@Override
	public R del(Long id) throws Exception {
		int isEnd = new TbUserPaySlip().setMonthPerformanceId(id).count();
		//已生成工资条的不能删除
		if(isEnd>0){
			return R.error("信息状态为“已生成”不能删除！");
		}

		int isDoMedicarePay = new TbMedicarePayItem().setUserMonthPerformanceId(id).count();
        if(isDoMedicarePay>0){
            return R.error("已生成医保付款单，不能删除！");
        }
        int isDoReservedPay = new TbReservedPayItem().setUserMonthPerformanceId(id).count();
        if(isDoReservedPay>0){
            return R.error("已生成公积金付款单，不能删除！");
        }
        int isDoSocialSecurityPay = new TbSocialSecurityPayItem().setUserMonthPerformanceId(id).count();
        if(isDoSocialSecurityPay>0){
            return R.error("已生成社保付款单，不能删除！");
        }

		tbUserMonthPerformanceMapper.deleteTrue(id);
		return R.ok();
	}



	/**
	 * 参数验证
	 */
	public String checkParams(Map<String, Object> params, Long menuId) throws Exception {
		//获取pc字段数据
		List<YsCol> listField = new YsCol()
				.where("A.MenuId = "+menuId)
				.setOrderby("A.SortNo ASC")
				.queryList();
		//验证必填字段的非空；其他字段的长度限制、类型
		String backMsg = checkUtil.checkTableColLengthAndDataType("TB_UserMonthPerformance",listField,params,ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1);
		//人事绩效评分不能大于100
		if(checkUtil.isNotNullByObject(params.get("hrPerformancePoint"))){
			BigDecimal hrPerformancePoint = new BigDecimal(params.get("hrPerformancePoint").toString());
			if(hrPerformancePoint.compareTo(new BigDecimal(100))>0){
				backMsg = "人事绩效评分不能大于100 ";
			}
		}
		return backMsg;
	}


	/**
	 * 同步员工考勤信息表id
	 */
	@Override
	public R updateUserAttendanceId(String countMonth) throws Exception {
		//获取月度绩效表信息
		List<TbUserMonthPerformance> tbUserMonthPerformanceList = new TbUserMonthPerformance().setPointMonth(countMonth).queryList();
		//获取员工考勤表信息
		List<TbUserAttendance> tbUserAttendanceList = new TbUserAttendance().setAttendanceMonth(countMonth).queryList();
		if(tbUserMonthPerformanceList!=null && tbUserMonthPerformanceList.size()>0 ) {
			if(tbUserAttendanceList!=null && tbUserAttendanceList.size()>0){
				for(TbUserMonthPerformance performanceItem : tbUserMonthPerformanceList){
					List<TbUserAttendance> tbUserAttendanceListByUserId = tbUserAttendanceList.stream()
							.filter(item->item.getUserId().equals(performanceItem.getUserId()))
							.collect(Collectors.toList());
					if(tbUserAttendanceListByUserId.size()>0){
						TbUserMonthPerformance updateItem = new TbUserMonthPerformance();
						updateItem.setId(performanceItem.getId());
						updateItem.setUserAttendanceId(tbUserAttendanceListByUserId.get(0).getId());
						updateItem.setWorkHour(tbUserAttendanceListByUserId.get(0).getWorkHour());
						updateItem.setAttendanceDay(tbUserAttendanceListByUserId.get(0).getAttendanceDay());
						updateItem.setBusinessTripsDay(tbUserAttendanceListByUserId.get(0).getBusinessTripsDay());
						updateItem.setRestDay(tbUserAttendanceListByUserId.get(0).getRestDay());
						updateItem.setNoWorkHour(tbUserAttendanceListByUserId.get(0).getNoWorkHour());
						updateItem.setLateTimes(tbUserAttendanceListByUserId.get(0).getLateTimes().intValue());
						updateItem.setNoSignIn(tbUserAttendanceListByUserId.get(0).getNoSignIn().intValue());
						updateItem.setYearHolidayHour(tbUserAttendanceListByUserId.get(0).getYearHolidayHour());
						updateItem.setChildbirthHolidayHour(tbUserAttendanceListByUserId.get(0).getChildbirthHolidayHour());
						updateItem.setCompanionChildbirthHour(tbUserAttendanceListByUserId.get(0).getCompanionChildbirthHour());
						updateItem.setMarryHolidayHour(tbUserAttendanceListByUserId.get(0).getMarryHolidayHour());
						updateItem.setDeathHolidayHour(tbUserAttendanceListByUserId.get(0).getDeathHolidayHour());
						updateItem.setIllHolidayHour(tbUserAttendanceListByUserId.get(0).getIllHolidayHour());
						updateItem.setThingHolidayHourByPublic(tbUserAttendanceListByUserId.get(0).getThingHolidayHourByPublic());
						updateItem.setThingHolidayHourByOther(tbUserAttendanceListByUserId.get(0).getThingHolidayHourByOther());
						updateItem.setAttendanceStatus(1);
						tbUserMonthPerformanceMapper.update(updateItem);
					}else {
						TbUserMonthPerformance updateItem = new TbUserMonthPerformance();
						updateItem.setId(performanceItem.getId());
						updateItem.setUserAttendanceId(0L);
						updateItem.setWorkHour(BigDecimal.ZERO);
						updateItem.setAttendanceDay(BigDecimal.ZERO);
						updateItem.setBusinessTripsDay(BigDecimal.ZERO);
						updateItem.setRestDay(BigDecimal.ZERO);
						updateItem.setNoWorkHour(BigDecimal.ZERO);
						updateItem.setLateTimes(0);
						updateItem.setNoSignIn(0);
						updateItem.setYearHolidayHour(BigDecimal.ZERO);
						updateItem.setChildbirthHolidayHour(BigDecimal.ZERO);
						updateItem.setCompanionChildbirthHour(BigDecimal.ZERO);
						updateItem.setMarryHolidayHour(BigDecimal.ZERO);
						updateItem.setDeathHolidayHour(BigDecimal.ZERO);
						updateItem.setIllHolidayHour(BigDecimal.ZERO);
						updateItem.setThingHolidayHourByPublic(BigDecimal.ZERO);
						updateItem.setThingHolidayHourByOther(BigDecimal.ZERO);
						updateItem.setAttendanceStatus(1);
						tbUserMonthPerformanceMapper.update(updateItem);
					}
				}
				return R.ok();
			}else {
				return R.error("该月的员工考勤信息暂未同步，请到员工考勤表信息页面中同步该月的考勤信息！");
			}
		}else {
			return R.error("该月暂无月度绩效信息！");
		}
	}



	/**
	 * 同步员工考勤信息表id
	 */
	@Override
	public R updateUserAttendanceIdById(Long id) throws Exception {
		//获取月度绩效表信息
		TbUserMonthPerformance tbUserMonthPerformance = new TbUserMonthPerformance().setId(id).queryFirst();

		if(tbUserMonthPerformance!=null && tbUserMonthPerformance.getPointMonth()!=null ) {
			//获取员工考勤表信息
			TbUserAttendance tbUserAttendanceListByUserId = new TbUserAttendance()
					.setAttendanceMonth(tbUserMonthPerformance.getPointMonth())
					.setUserId(tbUserMonthPerformance.getUserId())
					.queryFirst();
			if(tbUserAttendanceListByUserId!=null && tbUserAttendanceListByUserId.getCreateTime()!=null){
				TbUserMonthPerformance updateItem = new TbUserMonthPerformance();
				updateItem.setId(id);
				updateItem.setUserAttendanceId(tbUserAttendanceListByUserId.getId());
				updateItem.setWorkHour(tbUserAttendanceListByUserId.getWorkHour());
				updateItem.setAttendanceDay(tbUserAttendanceListByUserId.getAttendanceDay());
				updateItem.setBusinessTripsDay(tbUserAttendanceListByUserId.getBusinessTripsDay());
				updateItem.setRestDay(tbUserAttendanceListByUserId.getRestDay());
				updateItem.setNoWorkHour(tbUserAttendanceListByUserId.getNoWorkHour());
				updateItem.setLateTimes(tbUserAttendanceListByUserId.getLateTimes().intValue());
				updateItem.setNoSignIn(tbUserAttendanceListByUserId.getNoSignIn().intValue());
				updateItem.setYearHolidayHour(tbUserAttendanceListByUserId.getYearHolidayHour());
				updateItem.setChildbirthHolidayHour(tbUserAttendanceListByUserId.getChildbirthHolidayHour());
				updateItem.setCompanionChildbirthHour(tbUserAttendanceListByUserId.getCompanionChildbirthHour());
				updateItem.setMarryHolidayHour(tbUserAttendanceListByUserId.getMarryHolidayHour());
				updateItem.setDeathHolidayHour(tbUserAttendanceListByUserId.getDeathHolidayHour());
				updateItem.setIllHolidayHour(tbUserAttendanceListByUserId.getIllHolidayHour());
				updateItem.setThingHolidayHourByPublic(tbUserAttendanceListByUserId.getThingHolidayHourByPublic());
				updateItem.setThingHolidayHourByOther(tbUserAttendanceListByUserId.getThingHolidayHourByOther());
				updateItem.setAttendanceStatus(1);
				tbUserMonthPerformanceMapper.update(updateItem);
				return R.ok();
			}else {
				return R.error("该月的员工考勤信息暂未同步，请到员工考勤表信息页面中同步该月的考勤信息！");
			}
		}else {
			return R.error("该月暂无月度绩效信息！");
		}
	}



	/**
	 * 修改员工考勤状态
	 */
	@Override
	public R updateAttendanceStatus(Long id) throws Exception {
		//获取月度绩效表信息
		TbUserMonthPerformance tbUserMonthPerformance = new TbUserMonthPerformance().setId(id).queryFirst();
		if(tbUserMonthPerformance!=null && tbUserMonthPerformance.getAttendanceStatus()!=null  && tbUserMonthPerformance.getAttendanceStatus()==0 ) {
			tbUserMonthPerformance.setAttendanceStatus(2);
			tbUserMonthPerformanceMapper.update(tbUserMonthPerformance);
			return R.ok();
		}else {
			return R.error("只有考勤状态是未导入的才可变更状态！");
		}

	}




}
